<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript">
    /*
    总结：
    1、类中的构造器不是必须写的，只有要对示例进行一些初始化的操作，如添加指定属性才写
    2、如果B继承了A，且在B中写了构造器，那么B类构造器中的super是必须要调用的
    3、类中所定义的方法都是放在了累的原型对象上，供示例使用
    */
        //创建一个Person类
        class Person{
            //构造器方法
            constructor(name, age){
                //构造器中的this指的是谁呢？  -- 类的示例对象
                this.name = name
                this.age = age
            }
            //一般方法
            speak(){
                //speak方法放在了哪里？ --类的原型对象上
                //speak是给谁用的？ -- 供实例使用
                console.log(`我叫${this.name}, 我年龄是${this.age}`)
            }
        }
        // 创建一个Student类，继承于Person类
        class Student extends Person{
            constructor(name, age, grade){
                super(name, age)
                this.grade = grade

            }

            speak(){
                console.log(`我的名字是${this.name}, 我的年龄是${this.age}, 我在上${this.grade}年级`)
            }
        }

        class Car {
            constructor(name,price){
                this.name = name
                this.price = price

            }
            //类中可以直接写赋值语句
            //如下代码的含义是：给Car的示例对象添加一个属性，名为a值为1
            wheel = 4

        }
        const c1 = Car("奔驰c63",1899)
        const c2 = Car("宝马",899)
        console.log(c1)
        //创建一个Person的示例对象
        const p1 = new Person("Tom", 18)
        const p2 = new Person("Jerry", 19)
        const s1 = new Student('Jack', 20, "高一")

        console.log(p1)
        console.log(p2)
        console.log(s1)
        p1.speak()
        p2.speak()
        s1.speak()
        //call可以修改this指向
        p1.speak.call({"a":1,"b":2})
        

    </script>
</body>
</html>